package interfaces.hud.topWindows;

import java.util.concurrent.Callable;

import org.fenggui.binding.render.ITexture;
import org.fenggui.binding.render.ImageFont;
import org.fenggui.binding.render.Pixmap;
import org.fenggui.decorator.background.PixmapBackground;
import org.fenggui.util.Color;

import com.jme.util.GameTaskQueueManager;

import logic.common.game.Game;
import logic.common.player.Player;
import logic.common.team.Team;
import logic.common.team.teamListeners.DroneKillEvent;
import logic.common.team.teamListeners.TeamListener;
import logic.common.team.teamListeners.TeamValueChangedEvent;
import logic.common.team.teamListeners.TeamValueType;
import main.listeners.listenerClasses.GameListener;
import map.spawnStation.SpawnStation;
import map.spawnStation.stationListeners.ConquerHelpedEvent;
import map.spawnStation.stationListeners.SpawnStationListener;
import map.spawnStation.stationListeners.StationConqueredEvent;
import interfaces.GUISource;
import interfaces.hud.BasicHUD;
import interfaces.spawnMenu.spawnMap.SpawnButtonContent;
import interfaces.superWidgets.InterfaceButton;
import interfaces.superWidgets.InterfaceLabel;

public class ConquestStatusWindow extends TopHUDWindow {
	
	private InterfaceLabel ticketsA, ticketsB;
	private ImageFont labelFont;
	private int labelY, labelHeight, labelWidth;
	
	public ConquestStatusWindow(Game game, BasicHUD hud) {
		super(game, hud, hud.getWidth() / 4, hud.getHeight() / 20);
		
		labelFont = GUISource.middleFont;
		labelY = 0;
		labelHeight = content.getHeight();
		labelWidth = content.getWidth() / 6;
		
		initScoreLabels();
		initListener(game.getTeamA());
		initListener(game.getTeamB());
		if(game.isRunning()) initSpawnStations();
		
		hud.getHUDState().addListenerToClearer(new GameListener() {
			@Override
			public void gameStarted() {
				GameTaskQueueManager.getManager().update(new Callable<Void>() {
					@Override
					public Void call() throws Exception {
						initSpawnStations();
						return null;
					}
				});
			}
			
			@Override
			public void gameFinished() {}
			@Override
			public void gameDestroyed() {}
		});
		
		layout();
	}
	
	private void initSpawnStations() {
		int border = content.getHeight() / 7;
		int height = content.getHeight() - (2 * border);
		int width = height;
		int y = border;
		
		int ticketsBBorder = content.getWidth() - ticketsB.getX() - labelWidth;
		int stationsWidth = content.getWidth() - (labelWidth * 2) - ticketsA.getX() - ticketsBBorder;
		
		int stations = game.getMap().getSpawnStations().size();
		int dist = (stationsWidth - (stations * width)) / (stations + 1);
		int x = ticketsA.getWidth() + dist;
		
		for(SpawnStation station : game.getMap().getSpawnStations()) {
			String imagePath = SpawnButtonContent.STATION_NEUTRAL_PATH;
			Color color = Color.GRAY;
			
			Team stationTeam = station.getTeam();
			if(stationTeam != null) {
				if(stationTeam == game.getCurrentPlayer().getTeam()) {
					imagePath = SpawnButtonContent.STATION_NORMAL_PATH;
					color = GUISource.green;
				} else {
					imagePath = SpawnButtonContent.STATION_ENEMY_PATH;
					color = Color.RED;
				}
			}
			
			final InterfaceButton button = new InterfaceButton(station.getStationLetter(), labelFont);
			button.setXY(x, y);
			button.setSize(width, height);
			changeButtonImage(button, imagePath, color);
			x += dist + width;
			content.addWidget(button);
			
			hud.addListener(station, new SpawnStationListener() {
				@Override
				public void stationNeutralized() {
					changeButtonImage(button, SpawnButtonContent.STATION_NEUTRAL_PATH, Color.GRAY);
				}

				@Override
				public void conquered(StationConqueredEvent event) {
					if(event.getConquerer().getTeam() == game.getCurrentPlayer().getTeam()) 
						changeButtonImage(button, SpawnButtonContent.STATION_NORMAL_PATH, GUISource.green);
					else changeButtonImage(button, SpawnButtonContent.STATION_ENEMY_PATH, Color.RED);
				}
				
				@Override
				public void helpedConquer(ConquerHelpedEvent event) {}
			});
		}
		
		layout();
	}
	
	private void changeButtonImage(InterfaceButton button, String imagePath, Color color) {
		button.getAppearance().removeAll();
		ITexture texture = GUISource.loadTexture(imagePath);
		if(texture == null) return;
		Pixmap pixmap = new Pixmap(texture);
		button.getAppearance().add(new PixmapBackground(pixmap, true));
		GUISource.setTextColor(button, color);
	}
	
	private void initScoreLabels() {
		int x = labelWidth / 4;
		ticketsA = getNewScoreLabel(x, game.getTeamA().getTickets());
		GUISource.setTextColor(ticketsA, getLabelColor(game.getTeamA()));
		
		x = content.getWidth() - labelWidth + (labelWidth / 5 * 2);
		ticketsB = getNewScoreLabel(x, game.getTeamB().getTickets());
		GUISource.setTextColor(ticketsB, getLabelColor(game.getTeamB()));
	}
	
	private Color getLabelColor(Team team) {
		return (team == game.getCurrentPlayer().getTeam() ? Color.BLUE : Color.RED);
	}
	
	private InterfaceLabel getNewScoreLabel(int x, int tickets) {
		InterfaceLabel scoreLabel = new InterfaceLabel(tickets + "", labelFont);
		scoreLabel.setXY(x, labelY);
		scoreLabel.setSize(labelWidth, labelHeight);
		content.addWidget(scoreLabel);
		return scoreLabel;
	}
	
	private void initListener(final Team team) {
		TeamListener l = new TeamListener() {
			@Override
			public void teamValueChanged(TeamValueChangedEvent event) {
				if(event.getType() == TeamValueType.Tickets) 
					updateTicketsLabel(team == game.getTeamA() ? ticketsA : ticketsB, team.getTickets());
			}
			
			@Override
			public void playerRemoved(Player player) {}
			@Override
			public void playerAdded(Player player) {}
			@Override
			public void droneDestroyed(DroneKillEvent event) {}
		};
		
		hud.addListener(team, l);
	}
	
	private void updateTicketsLabel(InterfaceLabel label, int tickets) {
		label.setText(tickets + "");
		
		if(label == ticketsB) {
			int x = content.getWidth() - labelFont.getWidth(label.getText()) - ticketsA.getX();
			label.setX(x);
		}
		
		layout();
	}
}